from pathlib import Path
from typing import Iterable

from rich.syntax import Syntax
from rich.traceback import Traceback

from textual.events import MouseEvent
from textual.widgets import DirectoryTree

from screens.file_reader import FileReadScreen
from screens.file_editor import FileEditScreen
from screens.message import MessageScreen
from screens.add_file import AddFileScreen

import os


class MyDirectoryTree(DirectoryTree):
        
    def filter_paths(self, paths: Iterable[Path]) -> Iterable[Path]:
        return [path for path in paths if not path.name.startswith(".")]
    
    def key_tab(self):
        self.app.query_one("#user_table").styles.border = ("solid", "orangered")
        self.app.query_one("#user_table").cursor_type = 'row'
        self.app.query_one("#tree_box").styles.border = ("solid", "white")

    # 当前光标同级目录插入文件
    def key_insert(self):
        cursor_node = self.cursor_node
        if os.path.isdir(str(cursor_node.data.path)):
            fold_path = str(cursor_node.data.path)
        elif os.path.isfile(str(cursor_node.data.path)):
            fold_path = str(cursor_node.parent.data.path)
        try:
            self.app.uninstall_screen("AddFile")
        finally:
            self.app.install_screen(AddFileScreen(fold_path=fold_path, file_type="file"),name="AddFile")
            def check_result(result: bool):
                if result:
                    if os.path.isdir(str(cursor_node.data.path)):
                        self.reload_node(cursor_node)
                    elif os.path.isfile(str(cursor_node.data.path)):
                        self.reload_node(cursor_node.parent)
            self.app.push_screen("AddFile", check_result)
    
    # 创建文件夹
    def key_plus(self):
        cursor_node = self.cursor_node
        if os.path.isdir(str(cursor_node.data.path)):
            fold_path = str(cursor_node.data.path)
        elif os.path.isfile(str(cursor_node.data.path)):
            fold_path = str(cursor_node.parent.data.path)
        try:
            self.app.uninstall_screen("AddFile")
        finally:
            self.app.install_screen(AddFileScreen(fold_path=fold_path, file_type="fold"),name="AddFile")
            def check_result(result: bool):
                if result:
                    if os.path.isdir(str(cursor_node.data.path)):
                        self.reload_node(cursor_node)
                    elif os.path.isfile(str(cursor_node.data.path)):
                        self.reload_node(cursor_node.parent)
                    self.app.update_disk_label()
            self.app.push_screen("AddFile", check_result)

    # 删除当前光标文件
    def key_delete(self):
        try:
            self.app.uninstall_screen("DeleteFile")
        finally:
            delete_node = self.cursor_node
            self.app.install_screen(MessageScreen(f"是否删除{str(delete_node.data.path)}？"),name="DeleteFile")
            async def check_result(result: bool):
                if result:
                    os.system("rm -rf "+str(delete_node.data.path))
                    try:
                        self.reload_node(delete_node.parent.parent)
                    except:
                        self.reload_node(delete_node.parent)
                    self.app.update_disk_label()
            self.app.push_screen("DeleteFile", check_result)

    def on_directory_tree_file_selected(self, event: DirectoryTree.FileSelected):
        """当选中一个文件"""
        event.stop()
        # 获取文件大小（可直接嵌入工程使用）
        # input:文件路径
        # output：文件大小，单位
        def getFileSize(filePath):
            fsize = os.path.getsize(filePath)	# 返回字节大小
            '''
            为了更好地显示，应该时刻保持显示一定整数形式，即单位自适应
            '''
            if fsize < 1024:
                return(str(round(fsize,2))+' B')
            else: 
                KBX = fsize/1024
                if KBX < 1024:
                    return(str(round(KBX,2))+' KB')
                else:
                    MBX = KBX /1024
                    if MBX < 1024:
                        return(str(round(MBX,2))+' MB')
                    else:
                        return(str(round(MBX/1024))+' GB')
        try:
            syntax = Syntax.from_path(
                str(event.path),
                line_numbers=True,
                word_wrap=False,
                indent_guides=True,
                theme="github-dark",
            )
        except Exception:
            try:
                self.app.uninstall_screen("File")
            finally:
                self.app.install_screen(FileReadScreen(file_content=Traceback(theme="github-dark", width=None), file_name="ERROR"),name="File")
        else:
            try:
                self.app.uninstall_screen("File")
            finally:
                self.app.install_screen(FileReadScreen(file_content=syntax, file_name=str(event.path)+' 文件大小: '+getFileSize(event.path)),name="File")
        
        def open_file_editor():
            try:
                self.app.uninstall_screen("FileEditor")
            finally:
                self.app.install_screen(FileEditScreen(file_name=str(event.path)), name="FileEditor")
                async def check_result(result: bool):
                    if result:
                        try:
                            self.app.uninstall_screen("SaveMessage")
                        finally:
                            self.app.install_screen(MessageScreen(text="保存成功！"),name="SaveMessage")
                            self.app.push_screen("SaveMessage")
                self.app.push_screen("FileEditor", check_result)
        async def check_result(result: bool):
            if result:
                open_file_editor()
        self.app.push_screen("File", check_result)

    def on_click(self,event:MouseEvent):
        if self.has_focus:
            self.app.query_one("#tree_box").styles.border = ("solid", "orangered")
            self.app.query_one("#user_table").styles.border = ("solid", "white")
            self.app.query_one("#user_table").cursor_type = 'none'
            self.app.query_one("#pid_table").styles.border = ("solid", "white")
            self.app.query_one("#pid_table").cursor_type = 'none'
        

